// 
//  Copyright 2011  reda
// 
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
// 
//        http://www.apache.org/licenses/LICENSE-2.0
// 
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
using System;
using ManiacMusicManager.Data.Core;
using NHibernate;
using ManiacMusicManager.Data.DAO.Ifaces;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
namespace ManiacMusicManager.Data.DAO
{
	public class LangageDAO : AbstractDAO<Langage>, ILangageDAO
	{
		public LangageDAO (ISession session)
			: base(session)
		{
		}
	
		#region Convention
		private readonly static IDictionary<string,string> convention = new Dictionary<string,string>() {
			{"aar", "Afar"}, {"abk", "Abkhazian"}, {"ace", "Achinese"}, {"ach", "Acoli"}, {"ada", "Adangme"}, {"afa", "Afro-Asiatic (Other)"},
			{"afh", "Afrihili"}, {"afr", "Afrikaans"}, {"aka", "Akan"}, {"akk", "Akkadian"}, {"alb", "Albanian"}, {"ale", "Aleut"},
			{"alg", "Algonquian Languages"}, {"amh", "Amharic"}, {"ang", "English, Old (ca. 450-1100)"}, {"apa", "Apache Languages"},
			{"ara", "Arabic"}, {"arc", "Aramaic"}, {"arm", "Armenian"}, {"arn", "Araucanian"}, {"arp", "Arapaho"},
			{"art", "Artificial (Other)"}, {"arw", "Arawak"}, {"asm", "Assamese"}, {"ath", "Athapascan Languages"}, {"ava", "Avaric"},
			{"ave", "Avestan"}, {"awa", "Awadhi"}, {"aym", "Aymara"}, {"aze", "Azerbaijani"}, {"bad", "Banda"}, {"bai", "Bamileke Languages"},
			{"bak", "Bashkir"}, {"bal", "Baluchi"}, {"bam", "Bambara"}, {"ban", "Balinese"}, {"baq", "Basque"}, {"bas", "Basa"},
			{"bat", "Baltic (Other)"}, {"bej", "Beja"}, {"bel", "Byelorussian"}, {"bem", "Bemba"}, {"ben", "Bengali"},
			{"ber", "Berber (Other)"}, {"bho", "Bhojpuri"}, {"bih", "Bihari"}, {"bik", "Bikol"}, {"bin", "Bini"}, {"bis", "Bislama"},
			{"bla", "Siksika"}, {"bnt", "Bantu (Other)"}, {"bod", "Tibetan"}, {"bra", "Braj"}, {"bre", "Breton"}, {"bua", "Buriat"},
			{"bug", "Buginese"}, {"bul", "Bulgarian"}, {"bur", "Burmese"}, {"cad", "Caddo"}, {"cai", "Central American Indian (Other)"},
			{"car", "Carib"}, {"cat", "Catalan"}, {"cau", "Caucasian (Other)"}, {"ceb", "Cebuano"}, {"cel", "Celtic (Other)"},
			{"ces", "Czech"}, {"cha", "Chamorro"}, {"chb", "Chibcha"}, {"che", "Chechen"}, {"chg", "Chagatai"}, {"chi", "Chinese"},
			{"chm", "Mari"}, {"chn", "Chinook jargon"}, {"cho", "Choctaw"}, {"chr", "Cherokee"}, {"chu", "Church Slavic"}, {"chv", "Chuvash"},
			{"chy", "Cheyenne"}, {"cop", "Coptic"}, {"cor", "Cornish"}, {"cos", "Corsican"}, {"cpe", "Creoles and Pidgins, English-based (Other)"},
			{"cpf", "Creoles and Pidgins, French-based (Other)"}, {"cpp", "Creoles and Pidgins, Portuguese-based (Other)"}, {"cre", "Cree"},
			{"crp", "Creoles and Pidgins (Other)"}, {"cus", "Cushitic (Other)"}, {"cym", "Welsh"}, {"cze", "Czech"}, {"dak", "Dakota"},
			{"dan", "Danish"}, {"del", "Delaware"}, {"deu", "German"}, {"din", "Dinka"}, {"div", "Divehi"}, {"doi", "Dogri"}, {"dra", "Dravidian (Other)"},
			{"dua", "Duala"}, {"dum", "Dutch, Middle (ca. 1050-1350)"}, {"dut", "Dutch"}, {"dyu", "Dyula"}, {"dzo", "Dzongkha"}, {"efi", "Efik"},
			{"egy", "Egyptian (Ancient)"}, {"eka", "Ekajuk"}, {"ell", "Greek, Modern (1453-)"}, {"elx", "Elamite"}, {"eng", "English"},
			{"enm", "English, Middle (ca. 1100-1500)"}, {"epo", "Esperanto"}, {"esk", "Eskimo (Other)"}, {"esl", "Spanish"}, {"est", "Estonian"}, 
			{"eus", "Basque"}, {"ewe", "Ewe"}, {"ewo", "Ewondo"}, {"fan", "Fang"}, {"fao", "Faroese"}, {"fas", "Persian"}, {"fat", "Fanti"}, 
			{"fij", "Fijian"}, {"fin", "Finnish"}, {"fiu", "Finno-Ugrian (Other)"}, {"fon", "Fon"}, {"fra", "French"}, {"fre", "French"}, 
			{"frm", "French, Middle (ca. 1400-1600)"}, {"fro", "French, Old (842- ca. 1400)"}, {"fry", "Frisian"}, {"ful", "Fulah"}, {"gaa", "Ga"}, 
			{"gae", "Gaelic (Scots)"}, {"gai", "Irish"}, {"gay", "Gayo"}, {"gdh", "Gaelic (Scots)"}, {"gem", "Germanic (Other)"}, {"geo", "Georgian"},
			{"ger", "German"}, {"gez", "Geez"}, {"gil", "Gilbertese"}, {"glg", "Gallegan"}, {"gmh", "German, Middle High (ca. 1050-1500)"}, 
			{"goh", "German, Old High (ca. 750-1050)"}, {"gon", "Gondi"}, {"got", "Gothic"}, {"grb", "Grebo"}, {"grc", "Greek, Ancient (to 1453)"}, 
			{"gre", "Greek, Modern (1453-)"}, {"grn", "Guarani"}, {"guj", "Gujarati"}, {"hai", "Haida"}, {"hau", "Hausa"}, {"haw", "Hawaiian"}, 
			{"heb", "Hebrew"}, {"her", "Herero"}, {"hil", "Hiligaynon"}, {"him", "Himachali"}, {"hin", "Hindi"}, {"hmo", "Hiri Motu"}, 
			{"hun", "Hungarian"}, {"hup", "Hupa"}, {"hye", "Armenian"}, {"iba", "Iban"}, {"ibo", "Igbo"}, {"ice", "Icelandic"}, {"ijo", "Ijo"}, 
			{"iku", "Inuktitut"}, {"ilo", "Iloko"}, {"ina", "Interlingua (International Auxiliary language Association)"}, {"inc", "Indic (Other)"}, 
			{"ind", "Indonesian"}, {"ine", "Indo-European (Other)"}, {"ine2", "Interlingue"}, {"ipk", "Inupiak"}, {"ira", "Iranian (Other)"}, 
			{"iri", "Irish"}, {"iro", "Iroquoian uages"}, {"isl", "Icelandic"}, {"ita", "Italian"}, {"jav", "Javanese"}, {"jaw", "Javanese"}, 
			{"jpn", "Japanese"}, {"jpr", "Judeo-Persian"}, {"jrb", "Judeo-Arabic"}, {"kaa", "Kara-Kalpak"}, {"kab", "Kabyle"}, {"kac", "Kachin"}, 
			{"kal", "Greenlandic"}, {"kam", "Kamba"}, {"kan", "Kannada"}, {"kar", "Karen"}, {"kas", "Kashmiri"}, {"kat", "Georgian"}, {"kau", "Kanuri"},
			{"kaw", "Kawi"}, {"kaz", "Kazakh"}, {"kha", "Khasi"}, {"khi", "Khoisan (Other)"}, {"khm", "Khmer"}, {"kho", "Khotanese"}, {"kik", "Kikuyu"},
			{"kin", "Kinyarwanda"}, {"kir", "Kirghiz"}, {"kok", "Konkani"}, {"kom", "Komi"}, {"kon", "Kongo"}, {"kor", "Korean"}, {"kpe", "Kpelle"}, 
			{"kro", "Kru"}, {"kru", "Kurukh"}, {"kua", "Kuanyama"}, {"kum", "Kumyk"}, {"kur", "Kurdish"}, {"kus", "Kusaie"}, {"kut", "Kutenai"}, 
			{"lad", "Ladino"}, {"lah", "Lahnda"}, {"lam", "Lamba"}, {"lao", "Lao"}, {"lat", "Latin"}, {"lav", "Latvian"}, {"lez", "Lezghian"}, 
			{"lin", "Lingala"}, {"lit", "Lithuanian"}, {"lol", "Mongo"}, {"loz", "Lozi"}, {"ltz", "Letzeburgesch"}, {"lub", "Luba-Katanga"}, 
			{"lug", "Ganda"}, {"lui", "Luiseno"}, {"lun", "Lunda"}, {"luo", "Luo (Kenya and Tanzania)"}, {"mac", "Macedonian"}, {"mad", "Madurese"}, 
			{"mag", "Magahi"}, {"mah", "Marshall"}, {"mai", "Maithili"}, {"mak", "Macedonian"}, {"mak2", "Makasar"}, {"mal", "Malayalam"}, 
			{"man", "Mandingo"}, {"mao", "Maori"}, {"map", "Austronesian (Other)"}, {"mar", "Marathi"}, {"mas", "Masai"}, {"max", "Manx"}, 
			{"may", "Malay"}, {"men", "Mende"}, {"mga", "Irish, Middle (900 - 1200)"}, {"mic", "Micmac"}, {"min", "Minangkabau"}, 
			{"mis", "Miscellaneous (Other)"}, {"mkh", "Mon-Kmer (Other)"}, {"mlg", "Malagasy"}, {"mlt", "Maltese"}, {"mni", "Manipuri"},
			{"mno", "Manobo Languages"}, {"moh", "Mohawk"}, {"mol", "Moldavian"}, {"mon", "Mongolian"}, {"mos", "Mossi"}, {"mri", "Maori"}, 
			{"msa", "Malay"}, {"mul", "Multiple Languages"}, {"mun", "Munda Languages"}, {"mus", "Creek"}, {"mwr", "Marwari"}, {"mya", "Burmese"}, 
			{"myn", "Mayan Languages"}, {"nah", "Aztec"}, {"nai", "North American Indian (Other)"}, {"nau", "Nauru"}, {"nav", "Navajo"}, 
			{"nbl", "Ndebele, South"}, {"nde", "Ndebele, North"}, {"ndo", "Ndongo"}, {"nep", "Nepali"}, {"new", "Newari"}, 
			{"nic", "Niger-Kordofanian (Other)"}, {"niu", "Niuean"}, {"nla", "Dutch"}, {"nno", "Norwegian (Nynorsk)"}, {"non", "Norse, Old"}, 
			{"nor", "Norwegian"}, {"nso", "Sotho, Northern"}, {"nub", "Nubian Languages"}, {"nya", "Nyanja"}, {"nym", "Nyamwezi"}, {"nyn", "Nyankole"},
			{"nyo", "Nyoro"}, {"nzi", "Nzima"}, {"oci", "Langue d'Oc (post 1500)"}, {"oji", "Ojibwa"}, {"ori", "Oriya"}, {"orm", "Oromo"}, 
			{"osa", "Osage"}, {"oss", "Ossetic"}, {"ota", "Turkish, Ottoman (1500 - 1928)"}, {"oto", "Otomian Languages"}, 
			{"paa", "Papuan-Australian (Other)"}, {"pag", "Pangasinan"}, {"pal", "Pahlavi"}, {"pam", "Pampanga"}, {"pan", "Panjabi"}, 
			{"pap", "Papiamento"}, {"pau", "Palauan"}, {"peo", "Persian, Old (ca 600 - 400 B.C.)"}, {"per", "Persian"}, {"phn", "Phoenician"}, 
			{"pli", "Pali"}, {"pol", "Polish"}, {"pon", "Ponape"}, {"por", "Portuguese"}, {"pra", "Prakrit uages"}, 
			{"pro", "Provencal, Old (to 1500)"}, {"pus", "Pushto"}, {"que", "Quechua"}, {"raj", "Rajasthani"}, {"rar", "Rarotongan"}, 
			{"roa", "Romance (Other)"}, {"roh", "Rhaeto-Romance"}, {"rom", "Romany"}, {"ron", "Romanian"}, {"rum", "Romanian"}, {"run", "Rundi"}, 
			{"rus", "Russian"}, {"sad", "Sandawe"}, {"sag", "Sango"}, {"sah", "Yakut"}, {"sai", "South American Indian (Other)"}, 
			{"sal", "Salishan Languages"}, {"sam", "Samaritan Aramaic"}, {"san", "Sanskrit"}, {"sco", "Scots"}, {"scr", "Serbo-Croatian"}, 
			{"sel", "Selkup"}, {"sem", "Semitic (Other)"}, {"sga", "Irish, Old (to 900)"}, {"shn", "Shan"}, {"sid", "Sidamo"}, {"sin", "Singhalese"}, 
			{"sio", "Siouan Languages"}, {"sit", "Sino-Tibetan (Other)"}, {"sla", "Slavic (Other)"}, {"slk", "Slovak"}, {"slo", "Slovak"}, 
			{"slv", "Slovenian"}, {"smi", "Sami Languages"}, {"smo", "Samoan"}, {"sna", "Shona"}, {"snd", "Sindhi"}, {"sog", "Sogdian"}, 
			{"som", "Somali"}, {"son", "Songhai"}, {"sot", "Sotho, Southern"}, {"spa", "Spanish"}, {"sqi", "Albanian"}, {"srd", "Sardinian"}, 
			{"srr", "Serer"}, {"ssa", "Nilo-Saharan (Other)"}, {"ssw2", "Siswant"}, {"ssw", "Swazi"}, {"suk", "Sukuma"}, {"sun", "Sudanese"}, 
			{"sus", "Susu"}, {"sux", "Sumerian"}, {"sve", "Swedish"}, {"swa", "Swahili"}, {"swe", "Swedish"}, {"syr", "Syriac"}, {"tah", "Tahitian"},
			{"tam", "Tamil"}, {"tat", "Tatar"}, {"tel", "Telugu"}, {"tem", "Timne"}, {"ter", "Tereno"}, {"tgk", "Tajik"}, {"tgl", "Tagalog"}, 
			{"tha", "Thai"}, {"tib", "Tibetan"}, {"tig", "Tigre"}, {"tir", "Tigrinya"}, {"tiv", "Tivi"}, {"tli", "Tlingit"}, {"tmh", "Tamashek"}, 
			{"tog", "Tonga (Nyasa)"}, {"ton", "Tonga (Tonga Islands)"}, {"tru", "Truk"}, {"tsi", "Tsimshian"}, {"tsn", "Tswana"}, {"tso", "Tsonga"}, 
			{"tuk", "Turkmen"}, {"tum", "Tumbuka"}, {"tur", "Turkish"}, {"tut", "Altaic (Other)"}, {"twi", "Twi"}, {"tyv", "Tuvinian"}, 
			{"uga", "Ugaritic"}, {"uig", "Uighur"}, {"ukr", "Ukrainian"}, {"umb", "Umbundu"}, {"und", "Undetermined"}, {"urd", "Urdu"}, 
			{"uzb", "Uzbek"}, {"vai", "Vai"}, {"ven", "Venda"}, {"vie", "Vietnamese"}, {"vol", "Volapük"}, {"vot", "Votic"}, 
			{"wak", "Wakashan Languages"}, {"wal", "Walamo"}, {"war", "Waray"}, {"was", "Washo"}, {"wel", "Welsh"}, {"wen", "Sorbian Languages"}, 
			{"wol", "Wolof"}, {"xho", "Xhosa"}, {"yao", "Yao"}, {"yap", "Yap"}, {"yid", "Yiddish"}, {"yor", "Yoruba"}, {"zap", "Zapotec"}, 
			{"zen", "Zenaga"}, {"zha", "Zhuang"}, {"zho", "Chinese"}, {"zul", "Zulu"}, {"zun", "Zuni"}

		};
		#endregion

		#region Private
		private string PickNewCode(string name) {
			var prefix = name.ToLower().Substring(0, Math.Min(name.Length, 3));
			
			var list = (from a in this.Linq()
			            select a.Code);
			bool ok = false;
			int i = 0;
			do {
				i++;
				ok = list.Contains(prefix+i);
			} while(ok);
			
			return prefix+i;
		}
		#endregion
		
		#region ILangageDAO implementation
		public Langage InstanciateByName (string name)
		{
			var obj = this.GetByName(name);
			if(obj != null)
				return obj;
			
			
			foreach(var conv in convention) {
				var convName = conv.Value;
				var convCode = conv.Key;
				if(convName.ToLower()==name.ToLower())
					return new Langage() { Code = convCode , Name = convName };
			}
			
			TextInfo myTi = new CultureInfo("en-US",false).TextInfo;
			return new Langage() { Code = PickNewCode(name), Name = myTi.ToTitleCase(name) };
		}
		#endregion
	}
}

